home *** CD-ROM | disk | FTP | other *** search
- /* -------------------------------------------------------------------------- */
- /* -------------------------------------------------------------------------- */
-
- /*
- * UnZip - A ZIP file extract utility for ZIP files and ZIP ".EXE" files
- * archived using PKZIP 1.10 or earlier. Recognizes and dearchives “stored”,
- * “shrunk”, “reduced” and “imploded” files.
- *
- * VERSION: UnZip 1.02c — July 14, 1990
- *
- * Translated into Lightspeed C v.4.0 and adapted for the Mac by A.P. Maika,
- * (utilizing TransSkel 2.01 and TransDisplay 2.0 written by Paul DuBois)
- *
- * Dearchiving code for “extracting”, “unshrinking”, and “expanding” written
- * in Turbo C v. 2.0 © Samuel H. Smith (version 1.2 of 03-15-89)
- * Adapted for the Atari ST and CRC inline assembly code © Darin Wayrynen
- *
- * Dearchiving code for “exploding” derived from Turbo Pascal v. 5.0
- * source © R.P. Byrne (version 2.0 of 07-31-89)
- */
-
- /* -------------------------------------------------------------------------- */
- /* -------------------------------------------------------------------------- */
- /*
- * Host operating system details
- */
-
- #include <string.h>
- #include <stdlib.h>
- #include <unix.h>
- #include <fcntl.h>
- #include <TransDisplay.h>
-
- #define HIGH_LOW 1
-
- MenuHandle mFile,mOptions,mfilter,mstrip;
- CursHandle c;
- WindowRecord wprogressRec;
- WindowPtr wlist,wprogress;
- Point bloc = {40,40};
- Rect prect;
-
- SFReply SFzipfd;
- FInfo ffinfo;
-
- Boolean finishedflag,dirflag;
- Boolean stripLFflag=false;
- Boolean wlistflag=false;
- Boolean choosefileflag=false;
- Boolean TEXTfilterflag=false;
-
- char tstring[256],tfilename[256];
- long zipoffset[100],progresscount,sizeblock,fpos;
- int direntries,dindex,blockcount,numblocks;
-
- typedef struct gifinfo
- {
- char gif_signature[6];
- int screen_width;
- int screen_height;
- char color_resolution;
- } gifinfo;
-
- /* -------------------------------------------------------------------------- */
- /* stuff needed for exploding */
-
- #define LITERAL_TREE_ROOT 256
- #define DISTANCE_TREE_ROOT 64
- #define LENGTH_TREE_ROOT 64
-
- typedef struct SF_Node
- {
- int LChild;
- int RChild;
- } SF_Node;
-
- SF_Node SF_Literal[LITERAL_TREE_ROOT + 1];
- SF_Node SF_Distance[DISTANCE_TREE_ROOT + 1];;
- SF_Node SF_Length[LENGTH_TREE_ROOT + 1];
-
- typedef struct SF_BuildRec
- {
- int Len;
- int Val;
- int Code;
- } SF_BuildRec;
-
- int NextFreeLiteral;
- int NextFreeLength;
- int NextFreeDistance;
- int NumOfTrees;
- int MinMatchLen;
- int DictSize;
-
- /* -------------------------------------------------------------------------- */
- /* -------------------------------------------------------------------------- */
- /*
- * dearchiving code Copyright 1989 Samuel H. Smith; All rights reserved
- *
- * Do not distribute modified versions without my permission.
- * Do not remove or alter this notice or any other copyright notice.
- * If you use this in your own program you must distribute source code.
- * Do not use any of this in a commercial product.
- *
- */
-
- #define CODE_VERSION "UnZip: Zipfile Extract v1.2 of 03-15-89; (C) 1989 Samuel H. Smith"
-
- typedef unsigned char byte; /* code assumes UNSIGNED bytes */
- typedef long longint;
- typedef unsigned word;
- typedef char boolean;
-
- #define STRSIZ 256
-
- unsigned int in_size,out_size;
-
- /* -------------------------------------------------------------------------- */
- /*
- * Zipfile layout declarations
- */
-
- typedef longint signature_type;
-
-
- #define LOCAL_FILE_HEADER_SIGNATURE 0x504B0304L
-
-
- typedef struct local_file_header {
- word version_needed_to_extract;
- word general_purpose_bit_flag;
- int compression_method;
- int last_mod_file_time;
- int last_mod_file_date;
- longint crc32;
- longint compressed_size;
- longint uncompressed_size;
- int filename_length;
- int extra_field_length;
- } local_file_header;
-
-
- #define CENTRAL_FILE_HEADER_SIGNATURE 0x504B0102L
-
-
- typedef struct central_directory_file_header {
- word version_made_by;
- word version_needed_to_extract;
- word general_purpose_bit_flag;
- word compression_method;
- word last_mod_file_time;
- word last_mod_file_date;
- longint crc32;
- longint compressed_size;
- longint uncompressed_size;
- word filename_length;
- word extra_field_length;
- word file_comment_length;
- word disk_number_start;
- word internal_file_attributes;
- longint external_file_attributes;
- longint relative_offset_local_header;
- } central_directory_file_header;
-
-
- #define END_CENTRAL_DIR_SIGNATURE 0x504B0506L
-
-
- typedef struct end_central_dir_record {
- word number_this_disk;
- word number_disk_with_start_central_directory;
- word total_entries_central_dir_on_this_disk;
- word total_entries_central_dir;
- longint size_central_directory;
- longint offset_start_central_directory;
- word zipfile_comment_length;
- } end_central_dir_record;
-
-
-
- /* -------------------------------------------------------------------------- */
- /*
- * input file variables
- *
- */
-
- #define INBUFSIZ 0x2000L
- char *inbuf; /* input file buffer - any size is legal */
- char *inptr;
-
- int incnt;
- unsigned bitbuf;
- int bits_left;
- boolean zipeof;
-
- int zipfd;
-
- local_file_header lrec;
-
-
- /* -------------------------------------------------------------------------- */
- /*
- * output stream variables
- *
- */
-
- #define OUTBUFSIZ 0x6000L
- char *outbuf; /* buffer for rle look-back */
- char *outptr;
-
- long outpos; /* absolute position in outfile */
- unsigned int outcnt; /* current position in outbuf */
-
- int outfd;
- char filename[STRSIZ];
- char extra[STRSIZ];
-
- #define DLE 144
-
- /* -------------------------------------------------------------------------- */
- /*
- * shrink/reduce working storage
- *
- */
-
- int factor;
- byte followers[256][64];
- byte Slen[256];
-
- #define max_bits 13
- #define init_bits 9
- #define hsize 8192
- #define first_ent 257
- #define clear 256
-
- int *Prefix_of;
- byte *Suffix_of;
- byte *Stack;
-
- int codesize;
- int maxcode;
- int free_ent;
- int maxcodemax;
- int offset;
- int sizex;
-
- /* -------------------------------------------------------------------------- */
- void swap_bytes(wordp)
- word *wordp;
- /* convert intel style ‘short int’ variable to host format */
- {
- char *charp = (char *) wordp;
- char temp;
-
- temp = charp[0];
- charp[0] = charp[1];
- charp[1] = temp;
- }
-
- /* -------------------------------------------------------------------------- */
- void swap_lbytes(longp)
- longint *longp;
- /* convert intel style ‘long’ variable to host format */
- {
- char *charp = (char *) longp;
- char temp[4];
-
- temp[3] = charp[0];
- temp[2] = charp[1];
- temp[1] = charp[2];
- temp[0] = charp[3];
-
- charp[0] = temp[0];
- charp[1] = temp[1];
- charp[2] = temp[2];
- charp[3] = temp[3];
- }
-
-
- /* -------------------------------------------------------------------------- */
- int FillBuffer()
- /* fill input buffer if possible */
- {
- extern local_file_header lrec;
- unsigned int readsize;
-
- if (lrec.compressed_size <= 0 ) return (incnt = 0);
-
- if (lrec.compressed_size > (long) in_size) readsize = in_size;
- else readsize = (int) lrec.compressed_size;
-
- incnt = read(zipfd, inbuf, readsize);
-
- lrec.compressed_size -= incnt;
- inptr = inbuf;
- return (incnt--);
- }
-
- /* -------------------------------------------------------------------------- */
- int ReadByte(x)
- unsigned *x;
- /* read a byte; return 8 if byte available, 0 if not */
- {
- /* counter for UpdateProgressWind */
- if(sizeblock == ++progresscount)
- {
- progresscount = 0L;
- UpdateProgressWind(numblocks,++blockcount);
- }
-
- if (incnt-- == 0)
- if (FillBuffer() == 0)
- return 0;
-
- *x = *inptr++;
- return 8;
- }
-
-
- /* -------------------------------------------------------------------------- */
- static unsigned mask_bits[] =
- {0, 0x0001, 0x0003, 0x0007, 0x000f,
- 0x001f, 0x003f, 0x007f, 0x00ff,
- 0x01ff, 0x03ff, 0x07ff, 0x0fff,
- 0x1fff, 0x3fff, 0x7fff, 0xffff
- };
-
- /* -------------------------------------------------------------------------- */
- int FillBitBuffer(bits)
- register int bits;
- {
- /* get the bits that are left and read the next word */
- unsigned temp;
- register int result = bitbuf;
- int sbits = bits_left;
- bits -= bits_left;
-
- /* read next word of input */
- bits_left = ReadByte(&bitbuf);
- bitbuf = bitbuf & 0x00FF;
- bits_left += ReadByte(&temp);
- bitbuf |= (temp << 8);
- if (bits_left == 0)
- zipeof = 1;
-
- /* get the remaining bits */
- result = result | (int) ((bitbuf & mask_bits[bits]) << sbits);
- bitbuf >>= bits;
- bits_left -= bits;
- return result;
- }
-
- /* -------------------------------------------------------------------------- */
- #define READBIT(nbits,zdest) { if (nbits <= bits_left) { zdest = (int)(bitbuf & mask_bits[nbits]); bitbuf >>= nbits; bits_left -= nbits; } else zdest = FillBitBuffer(nbits);}
- /*
- * macro READBIT(nbits,zdest)
- * {
- * if (nbits <= bits_left) {
- * zdest = (int)(bitbuf & mask_bits[nbits]);
- * bitbuf >>= nbits;
- * bits_left -= nbits;
- * } else
- * zdest = FillBitBuffer(nbits);
- * }
- *
- */
-
-
- /* -------------------------------------------------------------------------- */
- #include "crc32.h"
-
- /* -------------------------------------------------------------------------- */
- void FlushOutput()
- /* flush contents of output buffer */
- {
- UpdateCRC(outbuf, outcnt);
- write(outfd, outbuf, outcnt);
- outpos = outpos + (long) outcnt;
- outcnt = 0;
- outptr = outbuf;
- }
-
- /* -------------------------------------------------------------------------- */
- #define OUTB(intc) { *outptr++=intc; if (++outcnt==out_size) FlushOutput(); }
- /*
- * macro OUTB(intc)
- * {
- * *outptr++=intc;
- * if (++outcnt==out_size)
- * FlushOutput();
- * }
- *
- */
-
- /* -------------------------------------------------------------------------- */
- void LoadFollowers()
- {
- register int x;
- register int i;
-
- for (x = 255; x >= 0; x--)
- {
- READBIT(6,Slen[x]);
- for (i = 0; i < Slen[x]; i++)
- {
- READBIT(8,followers[x][i]);
- }
- }
- }
-
- /* -------------------------------------------------------------------------- */
- /*
- * The Reducing algorithm is actually a combination of two
- * distinct algorithms. The first algorithm compresses repeated
- * byte sequences, and the second algorithm takes the compressed
- * stream from the first algorithm and applies a probabilistic
- * compression method.
- */
-
- int L_table[] = {0, 0x7f, 0x3f, 0x1f, 0x0f};
-
- int D_shift[] = {0, 0x07, 0x06, 0x05, 0x04};
- int D_mask[] = {0, 0x01, 0x03, 0x07, 0x0f};
-
- int B_table[] = {8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8};
-
- /* -------------------------------------------------------------------------- */
- void unReduce()
- /* expand probablisticly reduced data */
- {
- register int lchar;
- register int nchar;
- int ExState;
- register int V;
- register int Len;
- int ix,i,offset;
- long op;
-
- factor = lrec.compression_method - 1;
- ExState = 0;
- lchar = 0;
- LoadFollowers();
-
- while (((outpos + outcnt) < lrec.uncompressed_size) && (!zipeof))
- {
- if (Slen[lchar] == 0) READBIT(8,nchar) /* ; */
-
- else
- {
- READBIT(1,nchar);
- if (nchar != 0) READBIT(8,nchar) /* ; */
-
- else
- {
- int follower;
- int bitsneeded = B_table[Slen[lchar]];
- READBIT(bitsneeded,follower);
- nchar = followers[lchar][follower];
- }
- }
-
- /* expand the resulting byte */
- switch (ExState)
- {
-
- case 0:
- if (nchar != DLE) OUTB(nchar) /* ; */
-
- else
- ExState = 1;
-
- break;
-
- case 1:
- if (nchar != 0)
- {
- V = nchar;
- Len = V & L_table[factor];
- if (Len == L_table[factor]) ExState = 2;
- else ExState = 3;
- }
- else
- {
- OUTB(DLE);
- ExState = 0;
- }
- break;
-
- case 2:
- {
- Len += nchar;
- ExState = 3;
- }
- break;
-
- case 3:
- {
- i = Len + 3;
- offset = (((V >> D_shift[factor]) &
- D_mask[factor]) << 8) + nchar + 1;
- op = outpos + outcnt - offset;
-
- /* special case- before start of file */
- while ((op < 0L) && (i > 0))
- {
- OUTB(0);
- op++;
- i--;
- }
-
- /* normal copy of data from output buffer */
- {
- ix = (int) (op % out_size);
-
- /* do a block memory copy if possible */
- if ( ((ix +i) < out_size) && ((outcnt+i) < out_size) )
- {
- memcpy(outptr,&outbuf[ix],i);
- outptr += i;
- outcnt += i;
- }
-
- /* otherwise copy byte by byte */
- else while (i--)
- {
- OUTB(outbuf[ix]);
- if (++ix >= out_size) ix = 0;
- }
- }
-
- ExState = 0;
- }
- break;
- }
-
- /* store character for next iteration */
- lchar = nchar;
- }
- }
-
- /* -------------------------------------------------------------------------- */
- /*
- * Shrinking is a Dynamic Ziv-Lempel-Welch compression algorithm
- * with partial clearing.
- *
- */
-
- void partial_clear()
- {
- extern int *Prefix_of;
- register int pr;
- register int cd;
-
- /* mark all nodes as potentially unused */
- for (cd = first_ent; cd < free_ent; cd++)
- *(Prefix_of + cd) |= 0x8000;
-
- /* unmark those that are used by other nodes */
- for (cd = first_ent; cd < free_ent; cd++) {
- pr = *(Prefix_of + cd) & 0x7fff; /* reference to another node? */
- if (pr >= first_ent) /* flag node as referenced */
- *(Prefix_of +pr) &= 0x7fff;
- }
-
- /* clear the ones that are still marked */
- for (cd = first_ent; cd < free_ent; cd++)
- if ((*(Prefix_of + cd) & 0x8000) != 0)
- *(Prefix_of + cd) = -1;
-
- /* find first cleared node as next free_ent */
- cd = first_ent;
- while ((cd < maxcodemax) && (*(Prefix_of + cd) != -1))
- cd++;
- free_ent = cd;
- }
-
- /* -------------------------------------------------------------------------- */
- void unShrink()
- {
- #define GetCode(dest) READBIT(codesize,dest)
-
- extern int *Prefix_of;
- extern byte *Suffix_of;
- extern local_file_header lrec;
- extern byte *Stack;
- register int code;
- register int stackp;
- int finchar;
- int oldcode;
- int incode;
- void partial_clear();
-
-
- /* decompress the file */
- maxcodemax = 1 << max_bits;
- codesize = init_bits;
- maxcode = (1 << codesize) - 1;
- free_ent = first_ent;
- offset = 0;
- sizex = 0;
-
- for (code = maxcodemax; code > 255; code--)
- *(Prefix_of + code) = -1;
-
- for (code = 255; code >= 0; code--)
- {
- *(Prefix_of + code) = 0;
- *(Suffix_of + code) = code;
- }
-
- GetCode(oldcode);
- if (zipeof) return;
- finchar = oldcode;
-
- OUTB(finchar);
-
- stackp = hsize;
-
- while (!zipeof)
- {
- GetCode(code);
- if (zipeof) return;
-
- while (code == clear)
- {
- GetCode(code);
- switch (code)
- {
-
- case 1:
- {
- codesize++;
- if (codesize == max_bits)
- maxcode = maxcodemax;
- else
- maxcode = (1 << codesize) - 1;
- }
- break;
-
- case 2:
- partial_clear();
- break;
-
- }
-
- GetCode(code);
- if (zipeof) return;
- }
-
-
- /* special case for KwKwK string */
- incode = code;
- if (*(Prefix_of + code) == -1)
- {
- *(Stack + --stackp) = finchar;
- code = oldcode;
- }
-
-
- /* generate output characters in reverse order */
- while (code >= first_ent)
- {
- *(Stack + --stackp) = *(Suffix_of + code);
- code = *(Prefix_of + code);
- }
-
- finchar = *(Suffix_of + code);
- *(Stack + --stackp) = finchar;
-
-
- /* and put them out in forward order, block copy */
- if ((hsize-stackp+outcnt) < out_size)
- {
- memcpy(outptr,Stack+stackp,hsize-stackp);
- outptr += hsize-stackp;
- outcnt += hsize-stackp;
- stackp = hsize;
- }
-
- /* output byte by byte if we can’t go by blocks */
- else while (stackp < hsize)
- OUTB(*(Stack + stackp++));
-
-
- /* generate new entry */
- code = free_ent;
- if (code < maxcodemax)
- {
- *(Prefix_of + code) = oldcode;
- *(Suffix_of + code) = finchar;
-
- do
- code++;
- while ((code < maxcodemax) && (*(Prefix_of + code) != -1));
-
- free_ent = code;
- }
-
- /* remember previous code */
- oldcode = incode;
- }
-
- }
-
- /* ------------------------------------------------------------------------- */
- void get_string(len,s)
- int len;
- char *s;
- {
- read(zipfd, s, len);
- s[len] = 0;
- }
-
- /* ------------------------------------------------------------------------- */
- /*memcpy(to,from,count)
- register char *to,*from;
- register unsigned int count;
- {
- for(;count>0;--count,++to,++from)
- *to=*from;
- }*/
-
- /* -------------------------------------------------------------------------- */
- /* -------------------------------------------------------------------------- */
- /*
- * Exploding code derived from Turbo Pascal v. 5.0 source © R.P. Byrne
- * (version 2.0 — July 31, 1989)
- *
- */
-
- /* -------------------------------------------------------------------------- */
- Bad_SF_Tree()
- {
- close(outfd);
- CloseProgressWind();
- DisplayString("\p -- bad Shannon-Fano decode tree -- file skipped\015");
- }
-
- /* -------------------------------------------------------------------------- */
- Boolean Add_SF_SubTree(SF_TreePtr,SF_NextFreePtr,CurrNode,SF_Code,SF_Len,SF_Val)
- SF_Node (*SF_TreePtr)[];
- int *SF_NextFreePtr;
- int CurrNode;
- int SF_Code;
- int SF_Len;
- int SF_Val;
- {
- int i;
-
- for (i=(SF_Len - 1); i>=1; i--)
- {
- if (0 >= CurrNode)
- {
- Bad_SF_Tree();
- return(true);
- }
-
- if ((SF_Code >> i) & 0x0001)
- {
- if (-999 == (*SF_TreePtr)[CurrNode].RChild)
- {
- (*SF_TreePtr)[CurrNode].RChild = *SF_NextFreePtr;
- (*SF_NextFreePtr)--;
- }
- CurrNode = (*SF_TreePtr)[CurrNode].RChild;
- }
-
- else
- {
- if (-999 == (*SF_TreePtr)[CurrNode].LChild)
- {
- (*SF_TreePtr)[CurrNode].LChild = *SF_NextFreePtr;
- (*SF_NextFreePtr)--;
- }
- CurrNode = (*SF_TreePtr)[CurrNode].LChild;
- }
- }
-
- if (SF_Code & 0x0001)
- {
- if (-999 != (*SF_TreePtr)[CurrNode].RChild)
- {
- Bad_SF_Tree();
- return(true);
- }
-
- else (*SF_TreePtr)[CurrNode].RChild = -SF_Val;
- }
-
- else
- {
- if (-999 != (*SF_TreePtr)[CurrNode].LChild)
- {
- Bad_SF_Tree();
- return(true);
- }
-
- else (*SF_TreePtr)[CurrNode].LChild = -SF_Val;
- }
-
- return (false);
- }
-
- /* -------------------------------------------------------------------------- */
- Boolean Construct_SF_Tree(SF_TreePtr,SF_NextFreePtr,treesize)
- SF_Node (*SF_TreePtr)[];
- int *SF_NextFreePtr;
- int treesize;
- {
- static int swapsize[]={9,5,3,2,1};
-
- SF_BuildRec SF_Build[256];
- SF_BuildRec tempnode;
-
- int OneByte;
- char CodeLen;
- char CodeCount;
-
- int SF_Table_Codes;
- int SF_Build_Idx;
- int BuildCount;
-
- unsigned int Code;
- unsigned int CodeIncrement;
- int LastBitLength;
-
- register int i,j,k,s;
- int w,tLen,tVal;
-
- SF_Build_Idx = 0;
- BuildCount = 0;
- if(0 == ReadByte(&SF_Table_Codes))
- {
- DisplayString("\p -- unexpected end of file -- file skipped");
- return(true);
- }
-
- for (i=0; i<=SF_Table_Codes; i++)
- {
- if(0 == ReadByte(&OneByte))
- {
- DisplayString("\p -- unexpected end of file -- file skipped");
- return(true);
- }
- CodeLen = (OneByte & 0x000F) + 1;
- CodeCount = (OneByte >> 4) & 0x000F;
-
- for (j=0; j<=CodeCount; j++)
- {
- SF_Build[SF_Build_Idx].Len = CodeLen;
- SF_Build[SF_Build_Idx].Val = SF_Build_Idx;
- SF_Build_Idx++;
- }
- }
- BuildCount = SF_Build_Idx - 1;
-
- /* Shell sort of tree leaves */
- for (w=0; w<5; w++)
- {
- k = swapsize[w];
- s = -k;
- for (i=k; i<=BuildCount; ++i)
- {
- tLen = SF_Build[i].Len;
- tVal = SF_Build[i].Val;
- j = i - k;
- if (s==0)
- {
- s = -k;
- s++;
- SF_Build[s].Len = tLen;
- SF_Build[s].Val = tVal;
- }
- while (((tLen < SF_Build[j].Len) ||
- ((tLen == SF_Build[j].Len) && (tVal < SF_Build[j].Val)))
- && j>=0 && j<=BuildCount+1)
- {
- SF_Build[j+k].Len = SF_Build[j].Len;
- SF_Build[j+k].Val = SF_Build[j].Val;
- j = j - k;
- }
- SF_Build[j+k].Len = tLen;
- SF_Build[j+k].Val = tVal;
- }
- }
-
- Code = 0;
- CodeIncrement = 0;
- LastBitLength = 0;
-
- for (i=BuildCount; i>=0; i--)
- {
- Code = Code + CodeIncrement;
-
- if(SF_Build[i].Len != LastBitLength)
- {
- LastBitLength = SF_Build[i].Len;
- CodeIncrement = 1 << (16 - LastBitLength);
- }
- SF_Build[i].Code = Code >> (16 - SF_Build[i].Len);
-
- /* sprintf(tstring,"\r%3d %3d %3d %4X",i,SF_Build[i].Len,SF_Build[i].Val,SF_Build[i].Code);
- DisplayString(CtoPstr(tstring)); */
-
- if(Add_SF_SubTree( SF_TreePtr,
- SF_NextFreePtr,
- treesize,
- SF_Build[i].Code,
- SF_Build[i].Len,
- SF_Build[i].Val )) return (true);
- }
- /* for (i=0;i<=treesize;i++)
- fprintf(sftrees,"\r%3d %3d %3d",i,(*SF_TreePtr)[i].LChild,(*SF_TreePtr)[i].RChild);
- fprintf(sftrees,"\r\r"); */
-
- return (false);
- }
-
- /* -------------------------------------------------------------------------- */
- Boolean Init_Explode()
- {
- int i;
-
- DictSize = (((lrec.general_purpose_bit_flag >> 1) & 0x01) * 4096) + 4096;
- NumOfTrees = ((lrec.general_purpose_bit_flag >> 2) & 0x01) + 2;
- MinMatchLen = NumOfTrees;
-
- for (i=0; i<=LENGTH_TREE_ROOT; i++)
- {
- SF_Length[i].LChild = -999;
- SF_Length[i].RChild = -999;
- }
- NextFreeLength = LENGTH_TREE_ROOT - 1;
-
- for (i=0; i<=DISTANCE_TREE_ROOT; i++)
- {
- SF_Distance[i].LChild = -999;
- SF_Distance[i].RChild = -999;
- }
- NextFreeDistance = DISTANCE_TREE_ROOT - 1;
-
- if(3==NumOfTrees)
- {
- for (i=0; i<=LITERAL_TREE_ROOT; i++)
- {
- SF_Literal[i].LChild = -999;
- SF_Literal[i].RChild = -999;
- }
- NextFreeLiteral = LITERAL_TREE_ROOT - 1;
- if(Construct_SF_Tree(&SF_Literal,&NextFreeLiteral,LITERAL_TREE_ROOT)) return(true);
- }
-
- if(Construct_SF_Tree(&SF_Length,&NextFreeLength,LENGTH_TREE_ROOT)) return(true);
- if(Construct_SF_Tree(&SF_Distance,&NextFreeDistance,DISTANCE_TREE_ROOT)) return(true);
-
- return (false);
- }
-
- /* -------------------------------------------------------------------------- */
- Boolean Decode_SF_Data(SF_TreePtr,CurrNode,OutputPtr)
- register SF_Node (*SF_TreePtr)[];
- register int CurrNode;
- int *OutputPtr;
- {
- register int OneBit;
-
- while (0 < CurrNode)
- {
- READBIT(1,OneBit);
-
- if (OneBit)
- {
- if (-999 == (*SF_TreePtr)[CurrNode].RChild)
- {
- Bad_SF_Tree();
- return(true);
- }
-
- else CurrNode = (*SF_TreePtr)[CurrNode].RChild;
- }
-
- else
- {
- if (-999 == (*SF_TreePtr)[CurrNode].LChild)
- {
- Bad_SF_Tree();
- return(true);
- }
-
- else CurrNode = (*SF_TreePtr)[CurrNode].LChild;
- }
- }
- *OutputPtr = -CurrNode;
- return (false);
- }
-
- /* -------------------------------------------------------------------------- */
- Boolean Explode()
- {
- extern byte *Stack;
-
- int DistVal;
- int Literal;
- int Length;
- int Distance;
- int NBits;
- int Mask;
-
- register int StackIdx;
- register int StackStart;
- register int OneByte;
- register int i;
-
- Boolean LiteralTreeflag;
-
- if(Init_Explode()) return;
-
- for (StackIdx=0; StackIdx<hsize+1; StackIdx++) *(Stack + StackIdx) = 0;
- StackIdx = 0;
-
- LiteralTreeflag = (3 == NumOfTrees);
-
- if ((8192 == DictSize))
- {
- NBits = 7;
- Mask = 0x1FFF;
- }
- else
- {
- NBits = 6;
- Mask = 0x0FFF;
- }
-
- while ((!zipeof) && ((outpos + outcnt) < lrec.uncompressed_size))
- {
- READBIT(1,OneByte);
- if (OneByte)
- {
- if(LiteralTreeflag)
- {
- if(Decode_SF_Data(&SF_Literal,LITERAL_TREE_ROOT,&Literal)) return (true);
- }
- else READBIT(8,Literal);
-
- OUTB(Literal);
- Stack[StackIdx] = (char) Literal;
- if(DictSize == ++StackIdx) StackIdx = 0;
- }
-
- else
- {
- READBIT(NBits,Distance);
- if(Decode_SF_Data(&SF_Distance,DISTANCE_TREE_ROOT,&DistVal)) return (true);
- Distance = (Distance | (DistVal << NBits)) & Mask;
-
- if(Decode_SF_Data(&SF_Length,LENGTH_TREE_ROOT,&Length)) return (true);
-
- if (63 == Length)
- {
- READBIT(8,i);
- Length = Length + i;
- }
-
- i = Length + MinMatchLen;
- StackStart = StackIdx - (Distance + 1);
- if(0 > StackStart) StackStart = StackStart + DictSize;
-
- while (i-- > 0)
- {
- OUTB(Stack[StackStart]);
- Stack[StackIdx] = Stack[StackStart];
- if(DictSize == ++StackIdx) StackIdx = 0;
- if(DictSize == ++StackStart) StackStart = 0;
- }
- }
- }
- return (false);
- }
-
- /* -------------------------------------------------------------------------- */
- /* -------------------------------------------------------------------------- */
- OSErr freeSpaceOnVol(vRef,pfreeBytes)
- int vRef;
- unsigned long *pfreeBytes;
- {
- HVolumeParam HPB;
- OSErr err;
- long temp;
-
- HPB.ioNamePtr = 0L;
- HPB.ioVRefNum = vRef;
- HPB.ioVolIndex = 0;
- err = PBHGetVInfo(&HPB,false);
- /* modification of July 14, 1990 - UnZip 1.02c to eliminate sign extension
- problem with HPB.ioVFrBlk which resulted in a negative number if the
- nnumber of free blocks exceeded 32767 */
- temp = HPB.ioVFrBlk;
- if(0 > temp) temp = 65536L + temp;
- if(err==noErr) *pfreeBytes = (unsigned long) temp * HPB.ioVAlBlkSiz;
- else *pfreeBytes = 0L;
-
- /* Monitor("HPB.ioVAlBlkSiz",(int) HPB.ioVAlBlkSiz,"HPB.ioVFrBlk",(int) HPB.ioVFrBlk,"temp",temp);*/
-
- return(err);
- }
-
- /* ------------------------------------------------------------------------- */
- Monitor(s1,v1,s2,v2,s3,v3)
- /* debugging routine to monitor variables */
- char s1[32],s2[32],s3[32];
- int v1,v2;
- long v3;
- {
- char ts1[60],ts2[60],ts3[60];
- sprintf(ts1,"%10d %s",v1,s1);
- sprintf(ts2,"%10d %s",v2,s2);
- sprintf(ts3,"%10ld %s",v3,s3);
- ParamText(CtoPstr(ts1),CtoPstr(ts2),CtoPstr(ts3),"\p");
- Alert(103,nil);
- }
-
- /* -------------------------------------------------------------------------- */
- InitProgressWind(dearchivingtype)
- char *dearchivingtype;
- {
- int width;
-
- wprogress = GetNewWindow(102,&wprogressRec,-1L);
- SetPort(wprogress);
- sprintf(tstring,"%s : %s %ld \304> %ld bytes",
- dearchivingtype,
- filename,
- lrec.compressed_size,
- lrec.uncompressed_size);
- TextFont(150);
- TextSize(9);
- TextFace(bold);
- width = StringWidth(CtoPstr(tstring));
- MoveTo(((416-width)/2),15);
- DrawString(tstring);
- SetRect(&prect,38,22,380,40);
- FrameRect(&prect);
-
- numblocks = 20;
- sizeblock = lrec.compressed_size/20L;
- if(50000L > lrec.compressed_size)
- {
- sizeblock = lrec.compressed_size/10L;
- numblocks = 10;
- }
- if(10000L > lrec.compressed_size)
- {
- sizeblock = lrec.compressed_size/4L;
- numblocks = 4;
- }
- if( 2000L > lrec.compressed_size)
- {
- sizeblock = lrec.compressed_size/2L;
- numblocks = 2;
- }
- progresscount = 0L;
- blockcount = 0;
- PenPat(gray);
- }
-
- /* -------------------------------------------------------------------------- */
- UpdateProgressWind(numblocks,blockcount)
- int numblocks,blockcount;
- {
- Rect r;
- /* if(blockcount > numblocks) blockcount = numblocks; */
- SetRect(&r,(39+(blockcount-1)*340/numblocks),23,(39+blockcount*340/numblocks),39);
- PaintRect(&r);
- }
-
- /* -------------------------------------------------------------------------- */
- CloseProgressWind()
- {
- CloseWindow(wprogress);
- }
-
- /* -------------------------------------------------------------------------- */
- Boolean check_abort()
- {
- EvQElPtr eq_p;
- Boolean f_found=false;
-
- eq_p = (EvQElPtr)(EventQueue.qHead);
- while(true)
- {
- if((eq_p->evtQWhat==keyDown || eq_p->evtQWhat == autoKey) &&
- (eq_p->evtQModifiers & cmdKey) && (eq_p->evtQMessage & charCodeMask) == '.')
- {
- Dequeue((QElemPtr)eq_p,&EventQueue);
- f_found = true;
- }
- if(eq_p == (EvQElPtr)EventQueue.qTail) break;
- eq_p = (EvQEl *)(eq_p->qLink);
- }
- return (f_found);
- }
-
- /* -------------------------------------------------------------------------- */
- void set_file_time()
- {
- HFileInfo FiInfo;
- unsigned char tfname[256];
- OSErr result;
- DateTimeRec dtr;
- long seconds;
-
- strcpy(tstring,filename);
- CtoPstr(tstring);
- memcpy(tfname,tstring,256);
- FiInfo.ioNamePtr = tfname;
- FiInfo.ioVRefNum = 0;
- FiInfo.ioFVersNum = 0;
- FiInfo.ioFDirIndex = 0;
-
- result = PBGetFInfo(&FiInfo,false);
-
- dtr.day = lrec.last_mod_file_date & 0x1F;
- dtr.month = (lrec.last_mod_file_date >> 5) & 0x0F;
- dtr.year = ((lrec.last_mod_file_date >> 9) & 0x7F) + 1980;
-
- dtr.second = 0;
- dtr.minute = (lrec.last_mod_file_time >> 5) & 0x3F;
- dtr.hour = (lrec.last_mod_file_time >>11) & 0x1F;
- dtr.second = 2*(lrec.last_mod_file_time & 0x1F);
-
- Date2Secs(&dtr,&seconds);
- FiInfo.ioFlCrDat = seconds;
- FiInfo.ioFlMdDat = seconds;
- result = PBSetFInfo(&FiInfo,false);
- }
-
- /* -------------------------------------------------------------------------- */
- int create_output_file()
- /* return non-0 if creat failed */
- {
- extern local_file_header lrec;
- long freebytes;
- int filerr;
-
- freeSpaceOnVol(SFzipfd.vRefNum,&freebytes);
- if(lrec.uncompressed_size > freebytes)
- {
- sprintf(tstring,"***********: %-12s -- no space on volume -- file skipped",filename);
- DisplayString(CtoPstr(tstring));
- return(1);
- }
-
- outfd = creat(filename, O_CREAT | O_RDWR | O_BINARY);
-
- if (outfd == EOF)
- {
- sprintf(tstring,"***********: %-12s -- can't create output file -- file skipped",filename);
- DisplayString(CtoPstr(tstring));
- return(1);
- }
-
- strcpy(tstring,filename);
- GetFInfo(CtoPstr(tstring),0,&ffinfo);
- ffinfo.fdCreator = 'pZIP';
- ffinfo.fdType = 'TEXT';
- if((0L<zipoffset[dindex]) && (NULL==strstr(filename,".GIF")) && (NULL==strstr(filename,".gif"))) ffinfo.fdType='pBIN';
- SetFInfo(tstring,0,&ffinfo);
-
- /* write a single byte at EOF to pre-allocate the file */
- lseek(outfd, lrec.uncompressed_size-1L, SEEK_SET);
-
- filerr = write(outfd, "?", 1);
-
- lseek(outfd, 0L, SEEK_SET);
- return(0);
- }
-
- /* ------------------------------------------------------------------------- */
- extract_member()
- {
- extern local_file_header lrec;
-
- gifinfo gi;
- char colors;
- int ncolors;
- long freebytes;
-
- unsigned b;
- FILE *in,*out;
- int ch;
-
- bits_left = 0;
- bitbuf = 0;
- incnt = 0;
- outpos = 0L;
- outcnt = 0;
- outptr = outbuf;
- zipeof = 0;
- crc32val = 0xFFFFFFFFL;
-
- /* create the output file with READ and WRITE permissions */
-
- if(7>lrec.compression_method)
- {
- if (create_output_file())
- {
- DisplayLn();
- SysBeep(1);
- return(1);
- }
- }
-
- switch (lrec.compression_method)
- {
-
- case 0: /* stored */
- {
- sprintf(tstring," Extracting: %-12s ", filename);
- DisplayString(CtoPstr(tstring));
-
- InitProgressWind("Extracting");
- while (ReadByte(&b)) OUTB(b);
- CloseProgressWind();
- }
- break;
-
- case 1:
- {
- sprintf(tstring,"UnShrinking: %-12s ", filename);
- DisplayString(CtoPstr(tstring));
-
- InitProgressWind("UnShrinking");
- unShrink();
- CloseProgressWind();
- }
- break;
-
- case 2:
- case 3:
- case 4:
- case 5:
- {
- sprintf(tstring," Expanding: %-12s ",filename);
- DisplayString(CtoPstr(tstring));
-
- InitProgressWind("Expanding");
- unReduce();
- CloseProgressWind();
- }
- break;
-
- case 6:
- {
- sprintf(tstring," Exploding: %-12s ",filename);
- DisplayString(CtoPstr(tstring));
- InitProgressWind("Exploding");
- if(Explode()) return;
- CloseProgressWind();
- }
- break;
-
- default:
- {
- sprintf(tstring," : %-12s -- unknown compression method -- file skipped\015",filename);
- DisplayString(CtoPstr(tstring));
- }
- }
-
- if(6<lrec.compression_method) return;
-
- /* write the last partial buffer, if any */
- if (outcnt > 0)
- {
- UpdateCRC(outbuf, outcnt);
- write(outfd, outbuf, outcnt);
- }
-
- crc32val = -1 - crc32val;
-
- if (crc32val != lrec.crc32)
- {
- sprintf(tstring," -- Bad CRC %08lX (should be %08lX)", lrec.crc32, crc32val);
- DisplayString(CtoPstr(tstring));
- }
- else DisplayString("\p -- successful");
-
- /* if file ended in '.GIF' or '.gif' display additional GIF file info */
- if((NULL!=strstr(filename,".GIF")) || (NULL!=strstr(filename,".gif")))
- {
- lseek(outfd,0L,0L);
- read(outfd,tstring,sizeof(gifinfo));
- memcpy(&gi,tstring,sizeof(gifinfo));
- swap_bytes(&gi.screen_width);
- swap_bytes(&gi.screen_height);
- colors = gi.color_resolution & '\007';
- ncolors = 1 << (1+(int) colors);
- sprintf(tstring,"\015 -- GIF file: %dx%d %d colors",gi.screen_width,gi.screen_height,ncolors);
- DisplayString(CtoPstr(tstring));
- }
-
- close(outfd);
-
- /* strip linefeeds from text files if stripLFflag = true */
- if (stripLFflag && (0>zipoffset[dindex]))
- {
- freeSpaceOnVol(SFzipfd.vRefNum,&freebytes);
- if(lrec.uncompressed_size > freebytes)
- {
- DisplayString("\p\015 -- no space on volume for LF stripped file");
- }
- else
- {
- DisplayString("\p\015 -- stripping LF's ");
- in = fopen(filename,"rb");
- out = fopen("pZIPtemp01","wb");
-
- if (out != NULL)
- {
- strcpy(tstring,"pZIPtemp01");
- GetFInfo(CtoPstr(tstring),0,&ffinfo);
- ffinfo.fdCreator = 'pZIP';
- ffinfo.fdType = 'TEXT';
- SetFInfo(tstring,0,&ffinfo);
- outcnt = 0;
- outptr = outbuf;
-
- while ((ch=getc(in)) != EOF)
- if('\012' != ch)
- {
- *outptr++ = ch;
- if(++outcnt==out_size)
- {
- fwrite(outbuf,1,out_size,out);
- outcnt = 0;
- outptr = outbuf;
- }
- }
-
- /* write the last partial buffer, if any */
- if (outcnt > 0) fwrite (outbuf,1,outcnt,out);
-
- fclose(in);
- fclose(out);
- remove(filename);
- rename("pZIPtemp01",filename);
- DisplayString("\p -- successful");
- }
- else
- {
- DisplayString("\p\015 -- error opening LF stripped file -- skipped");
- }
-
- }
- }
-
- /* set output file date and time */
- set_file_time();
- DisplayLn();
- }
-
- /* ------------------------------------------------------------------------- */
- void process_local_file_header()
- {
- extern local_file_header lrec;
- char temp[256];
-
- read(zipfd, tstring, sizeof(lrec));
- memcpy(&lrec,tstring,sizeof(lrec));
-
- swap_bytes(&lrec.filename_length);
- swap_bytes(&lrec.extra_field_length);
- swap_lbytes(&lrec.compressed_size);
- swap_lbytes(&lrec.uncompressed_size);
- swap_bytes(&lrec.last_mod_file_time);
- swap_bytes(&lrec.last_mod_file_date);
- swap_bytes(&lrec.compression_method);
- swap_bytes(&lrec.general_purpose_bit_flag);
- swap_lbytes(&lrec.crc32);
-
- get_string(lrec.filename_length, filename);
- get_string(lrec.extra_field_length, extra);
-
- if(TEXTfilterflag && (0L<zipoffset[dindex]) && (NULL==strstr(filename,".GIF")) && (NULL==strstr(filename,".gif"))) return;
-
- if (choosefileflag)
- {
- strcpy(tstring,"Dearchive “");
- strcat(tstring,filename);
- strcat(tstring,"”?");
- ParamText(CtoPstr(tstring),"\p","\p","\p");
- InitCursor();
- if(1==Alert (102,nil))
- {
- c = GetCursor(watchCursor);
- SetCursor(*c);
- extract_member();
- }
- }
- else extract_member();
- }
-
- /* -------------------------------------------------------------------------- */
- long process_central_file_header()
- {
- central_directory_file_header rec;
- char filename[STRSIZ];
- char extra[STRSIZ];
- char comment[STRSIZ];
- static char *method[8]={" Stored"," Shrunk"," Reduced1"," Reduced2"," Reduced3"," Reduced4"," Imploded"," Unknown"};
- static char *ny[2]={" no","yes"};
- static char *mo[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
- long offset;
- int day,month,year,hour,minute,second;
-
- if (dirflag)
- {
- memcpy(&rec,inbuf+incnt,sizeof(rec));
- incnt = incnt + sizeof(rec);
- }
- else
- {
- read(zipfd,tstring,sizeof(rec));
- memcpy(&rec,tstring,sizeof(rec));
- }
-
- swap_bytes(&rec.compression_method);
- swap_lbytes(&rec.compressed_size);
- swap_lbytes(&rec.uncompressed_size);
- swap_bytes(&rec.last_mod_file_time);
- swap_bytes(&rec.last_mod_file_date);
- swap_lbytes(&rec.crc32);
- swap_bytes(&rec.internal_file_attributes);
- swap_bytes(&rec.filename_length);
- swap_bytes(&rec.extra_field_length);
- swap_bytes(&rec.file_comment_length);
- swap_lbytes(&rec.relative_offset_local_header);
-
- if (dirflag)
- {
- memcpy(filename,inbuf+incnt,rec.filename_length);
- filename[rec.filename_length] = 0;
- incnt = incnt + rec.filename_length;
- memcpy(extra,inbuf+incnt,rec.extra_field_length);
- extra[rec.extra_field_length] = 0;
- incnt = incnt + rec.extra_field_length;
- memcpy(comment,inbuf+incnt,rec.file_comment_length);
- comment[rec.file_comment_length] = 0;
- incnt = incnt + rec.file_comment_length;
- }
- else
- {
- get_string(rec.filename_length,filename);
- get_string(rec.extra_field_length,extra);
- get_string(rec.file_comment_length,comment);
- }
-
- if(6<rec.compression_method) rec.compression_method = 7;
-
- day = rec.last_mod_file_date & 0x1F;
- month = (rec.last_mod_file_date >> 5) & 0x0F;
- year = ((rec.last_mod_file_date >> 9) & 0x7F) + 80;
-
- hour = (rec.last_mod_file_time >>11) & 0x1F;
- minute = (rec.last_mod_file_time >> 5) & 0x3F;
- second = 2*(rec.last_mod_file_time & 0x1F);
-
- sprintf(tstring,"%-12s%s%10ld %10ld%4d-%3s-%2d %02d:%02d:%02d %08lX %3s\015",
- filename,
- method[rec.compression_method],
- rec.compressed_size,
- rec.uncompressed_size,
- day,
- mo[month-1],
- year,
- hour,
- minute,
- second,
- rec.crc32,
- ny[rec.internal_file_attributes]);
-
- DisplayString(CtoPstr(tstring));
- offset = 1L + rec.relative_offset_local_header;
- if (1==rec.internal_file_attributes) offset = -offset;
- return(offset);
- }
-
- /* ------------------------------------------------------------------------- */
- int process_end_central_dir()
- {
- end_central_dir_record rec;
- Rect drect;
-
- memcpy(&rec,inbuf+incnt+1,sizeof(rec));
- incnt = incnt + 1 + sizeof(rec);
-
- swap_bytes(&rec.total_entries_central_dir);
- swap_lbytes(&rec.offset_start_central_directory);
- swap_bytes(&rec.zipfile_comment_length);
-
- wlistflag = true;
- wlist = GetNewDWindow(101,-1L);
- SetWTitle(wlist,&SFzipfd.fName);
- SetDWindowStyle(wlist,150,9,1,0);
- DisplayText(inbuf+incnt,(long) rec.zipfile_comment_length);
-
- if(fpos < rec.offset_start_central_directory)
- {
- dirflag = true;
- incnt = rec.offset_start_central_directory - fpos;
- }
- else
- {
- dirflag = false;
- lseek(zipfd,rec.offset_start_central_directory,0);
- }
-
- return(rec.total_entries_central_dir);
- }
-
- /* ------------------------------------------------------------------------- */
- /*long labs(x)
- long x;
- {
- long y;
- y = x;
- if(0L>y) y = -y;
- return(y);
- }*/
-
- /* ------------------------------------------------------------------------- */
- void process_headers()
- {
- longint sig;
-
- Boolean abortflag=false;
-
- if(finishedflag)
- {
- SysBeep(1);
- strcpy(tstring,"\015ZIP file extraction completed for this file!");
- ParamText(CtoPstr(tstring),"\p","\p","\p");
- HiliteMenu(nil);
- (void) StopAlert(101,nil);
- return;
- }
-
- c = GetCursor(watchCursor);
- SetCursor(*c);
-
- for (dindex=0;dindex<direntries;dindex++)
- {
- lseek(zipfd,labs(zipoffset[dindex])-1,0);
-
- read(zipfd, tstring, sizeof(sig));
- memcpy(&sig,tstring,sizeof(sig));
-
- if (sig != LOCAL_FILE_HEADER_SIGNATURE)
- {
- DisplayString("\pBad ZIP file local header signature--file skipped\015");
- }
-
-
- else process_local_file_header();
- if(abortflag = check_abort())
- {
- DisplayString("\p\r * PROCESSING ABORTED *\r");
- ParamText("\p\rProcessing aborted!","\p","\p","\p");
- break;
- }
- }
- if(!abortflag) ParamText("\p\rZIP file extraction completed!","\p","\p","\p");
- InitCursor();
- close(zipfd);
- finishedflag = true;
- Delay(20L,sig);
- SysBeep(1);
- Delay(5L,sig);
- SysBeep(1);
- HiliteMenu(nil);
- (void) NoteAlert (101,nil);
- }
-
- /* ------------------------------------------------------------------------- */
- AllocateBuffers()
- {
- int buffer_fail = 0;
-
- extern int *Prefix_of;
- extern byte *Suffix_of;
- extern byte *Stack;
-
- int i;
-
- Prefix_of = calloc(hsize+1,2);
- Suffix_of = calloc(hsize+1,1);
- Stack = calloc(hsize+1,1);
-
- /* allocate i/o buffers */
- inbuf = (char *) (malloc(INBUFSIZ));
- outbuf = (char *) (malloc(OUTBUFSIZ));
- in_size = INBUFSIZ;
- out_size = OUTBUFSIZ;
-
- if ((inbuf == NULL) || (outbuf == NULL))
- {
- ParamText("\pInsufficient memory to allocate buffers!","\p","\p","\p");
- (void) StopAlert (101,nil);
- SkelWhoa();
- }
- }
-
- /* ------------------------------------------------------------------------- */
- aboutUnZip()
- {
- (void) Alert(100,nil);
- }
-
- /* ------------------------------------------------------------------------- */
- setLFflag()
- {
- if (!stripLFflag)
- {
- stripLFflag = true;
- CheckItem(mOptions,3,true);
- mstrip = NewMenu(5,"\p*Strip LF on*");
- SkelMenu(mstrip,nil,nil);
- }
- else
- {
- stripLFflag = false;
- CheckItem(mOptions,3,false);
- mstrip = NewMenu(5,"\p");
- SkelMenu(mstrip,nil,nil);
- }
- }
-
- /* ------------------------------------------------------------------------- */
- setTEXTfilterflag()
- {
- if (!TEXTfilterflag)
- {
- TEXTfilterflag = true;
- CheckItem(mOptions,4,true);
- mfilter = NewMenu(4,"\p*.GIF & TEXT filter*");
- SkelMenu(mfilter,nil,nil);
- }
- else
- {
- TEXTfilterflag = false;
- CheckItem(mOptions,4,false);
- mfilter = NewMenu(4,"\p");
- SkelMenu(mfilter,nil,nil);
- }
- }
-
- /* ------------------------------------------------------------------------- */
- setchoosefileflag()
- {
- if (!choosefileflag)
- {
- choosefileflag = true;
- CheckItem(mOptions,5,true);
- }
- else
- {
- choosefileflag = false;
- CheckItem(mOptions,5,false);
- }
- }
-
- /* ------------------------------------------------------------------------- */
- openfile()
- {
- extern int direntries;
- extern long fpos;
- long sig;
- long flength;
- long temp;
- int tbufsize;
- boolean foundecdflag;
-
- DisableItem(mOptions,1);
-
- if(wlistflag)
- {
- if (!finishedflag) close(zipfd);
- SkelRmveWind(wlist);
- wlistflag = false;
- }
- finishedflag = false;
-
- SFGetFile(bloc,"\p",nil,-1,nil,nil,&SFzipfd);
-
- if(!SFzipfd.good) return;
- else SetVol("\p",SFzipfd.vRefNum);
-
- c = GetCursor(watchCursor);
- SetCursor(*c);
- memcpy(tstring,&SFzipfd.fName,64);
- zipfd = open(PtoCstr(tstring), O_RDONLY | O_BINARY);
- flength = lseek(zipfd,0L,2);
- fpos = flength - 8192;
- tbufsize = 8192;
- if (0 > fpos)
- {
- fpos = 0;
- tbufsize = flength;
- }
-
- lseek(zipfd,-(long) tbufsize,2);
- read(zipfd,inbuf,tbufsize);
- foundecdflag = false;
-
- for (incnt=tbufsize-18; incnt>4; incnt--)
- {
- if (('\006'== *(inbuf + (long) incnt )) &&
- ('\005'== *(inbuf + (long) (incnt-1) )) &&
- ( 'K'== *(inbuf + (long) (incnt-2) )) &&
- ( 'P'== *(inbuf + (long) (incnt-3) )))
- {
- foundecdflag = true;
- break;
- }
- }
-
- if (!foundecdflag)
- {
- /* not a ZIP file alert */
- memcpy(tstring,&SFzipfd.fName,64);
- PtoCstr(tstring);
- strcat(tstring,"\015\015Not a ZIP file!");
- ParamText(CtoPstr(tstring),"\p","\p","\p");
- InitCursor();
- SysBeep(1);
- HiliteMenu(nil);
- (void) StopAlert (101,nil);
- close(zipfd);
- return;
- }
-
- direntries = process_end_central_dir();
-
- DisplayString("\p\015\015File Name Method Size Now Full Size Date Time CRC Text\015");
- DisplayString("\p--------- -------- -------- --------- --------- -------- -------- ----\015");
-
- for (dindex=0;dindex<direntries;dindex++)
- {
- if (dirflag)
- {
- memcpy(&sig,inbuf+incnt,sizeof(sig));
- incnt = incnt + sizeof(sig);
- }
- else
- {
- read(zipfd,tstring,sizeof(sig));
- memcpy(&sig,tstring,sizeof(sig));
- }
-
- if (sig == CENTRAL_FILE_HEADER_SIGNATURE) zipoffset[dindex]=process_central_file_header();
-
- }
- DisplayLn();
- InitCursor();
- EnableItem(mOptions,1);
- SysBeep(6);
- SetDWindowPos(wlist,0);
- ShowWindow(wlist);
- }
-
- /* ------------------------------------------------------------------------- */
- DoFileMenu(item)
- int item;
- {
- switch(item)
- {
- case 1: openfile(); break;
- case 2: {
- free(Prefix_of);
- free(Suffix_of);
- free(Stack);
- free(inbuf);
- free(outbuf);
- SkelWhoa();
- break;
- }
- }
- }
-
- /* ------------------------------------------------------------------------- */
- DoOptionsMenu(item)
- int item;
- {
- switch(item)
- {
- case 1: process_headers(); break;
- case 2: break;
- case 3: setLFflag(); break;
- case 4: setTEXTfilterflag();break;
- case 5: setchoosefileflag(); break;
- }
- }
-
- /* ------------------------------------------------------------------------- */
- void main()
- {
- SkelInit(6,nil);
- SkelApple("\pAbout UnZip 1.02c…",aboutUnZip);
-
- mFile = GetMenu(101);
- (void) SkelMenu(mFile,DoFileMenu,nil,false);
- mOptions = GetMenu(102);
- (void) SkelMenu(mOptions,DoOptionsMenu,nil,true);
-
- AllocateBuffers();
- SkelMain();
- SkelClobber();
- }
-